package com.everydayflash.cart.mods {
	import com.as3dmod.ModifierStack;
	import com.as3dmod.modifiers.Twist;
	import com.as3dmod.util.Log;
	import com.everydayflash.cart.core.AbstractSketch;
	import com.everydayflash.cart.core.Pixel3D;
	import com.everydayflash.cart.mods.plugin.LibrarySimple;
	
	import flash.display.BitmapData;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix3D;
	import flash.geom.PerspectiveProjection;
	import flash.geom.Point;
	import flash.geom.Vector3D;	

	/**
	 * @author bartekd
	 */
	public class ModTwist extends AbstractSketch {
		
		private var pts:Vector.<Pixel3D>;
		
		private var projection:Matrix3D;
		private var matrix:Matrix3D;
		private var stack:ModifierStack;
		private var twist:Twist;
		private var ta:Number;

		override protected function init():void {
			var p:PerspectiveProjection = new PerspectiveProjection();
			p.focalLength = 400;
			projection = p.toMatrix3D();
			matrix = new Matrix3D();
	
			pts = new Vector.<Pixel3D>();
			var xw:int = 1500;
			var yw:int = 200;
			var st:int = 10;
			
			Log.info(this, "init with " + ((xw * yw) / (st * st)) + " particles");

			for (var x:int = 0; x < xw; x += st) {
				for (var y:int = 0; y < yw; y += st) {
					var r:Pixel3D = new Pixel3D(x - xw / 2, y - yw / 2, 0);
					r.color = 0xffffff;
					pts.push(r);
				}
			}
			
			stack = new ModifierStack(new LibrarySimple(), pts);
			
			ta = 0;
			twist = new Twist(ta);
			twist.vector = new Vector3D(1, 0, 0);
			stack.addModifier(twist);
		}

		override protected function mouseDown(e:MouseEvent):void {
		}

		override protected function draw():void {
			ta += 0.04;
			twist.angle = Math.sin(ta) * 4;
			stack.apply();
			
//			clearBCanvas();
			
			bcanvas.applyFilter(bcanvas, bcanvas.rect, new Point(), new BlurFilter(2,2,1));
			bcanvas.colorTransform(bcanvas.rect, new ColorTransform(1,1,1,.9));
			
			var angleX:Number = (mouseX - sw/2) / sw/2 * 360;
			var angleY:Number = (mouseY - sh/2) / sh/2 * 360;

			for (var i:int = 0;i < pts.length; i++) {
				matrix.identity();
				matrix.appendRotation(angleX, new Vector3D(0, 1, 0));
				matrix.appendRotation(angleY, new Vector3D(1, 0, 0));
				matrix.appendTranslation(0, 0, 400);
			
				var v:Pixel3D = pts[i];
				
				var iv:Vector3D = matrix.transformVector(v);
				
				var vz:Number = 1 - (iv.z / 1000);
				vz = Math.min(1, vz);
				vz = Math.max(0, vz);
				
				if(iv.z < 0) continue;
				
				iv = projection.transformVector(iv);
				iv.project();

				var c:uint = (vz * 255) << 24 | v.color;
				
				bcanvas.setPixel32(sw / 2 + iv.x, sh/2 + iv.y, c);
			}
		}
	}
}
